home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 3 / Info_Mac_1994-01.iso / Development / Source / Macintosh Tracker 1.1 Source / Original Tracker 3.10 Source / ss10_audio.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-22  |  5.5 KB  |  280 lines  |  [TEXT/KAHL]

  1. /* ss10_audio.h */
  2.  
  3. /* $Id: ss10_audio.c,v 3.7 1993/01/06 17:58:39 espie Exp espie $
  4.  * $Log: ss10_audio.c,v $
  5.  * Revision 3.7  1993/01/06  17:58:39  espie
  6.  * *** empty log message ***
  7.  *
  8.  * Revision 3.6  1992/12/03  15:00:50  espie
  9.  * restore stty.
  10.  *
  11.  * Revision 3.5  1992/11/27  10:29:00  espie
  12.  * General cleanup
  13.  *
  14.  * Revision 3.4  1992/11/24  10:51:19  espie
  15.  * Sync pseudo call.
  16.  *
  17.  * Revision 3.3  1992/11/22  17:20:01  espie
  18.  * Added update_frequency call, mostly unchecked
  19.  *
  20.  * Revision 3.2  1992/11/20  14:53:32  espie
  21.  * Added finetune.
  22.  *
  23.  * Revision 3.1  1992/11/19  20:44:47  espie
  24.  * Protracker commands.
  25.  *
  26.  * Revision 3.0  1992/11/18  16:08:05  espie
  27.  * New release.
  28.  *
  29.  * Revision 1.3  1992/11/17  15:38:00  espie
  30.  * discard_buffer() call for snappier interface calls.
  31.  * - Unified support for all sparcs.
  32.  * - moved down to level 2 io.
  33.  */
  34.  
  35. #include <stdio.h>
  36. #include "defs.h"
  37. #include "extern.h"
  38. #include <sun/audioio.h>
  39. #include <sys/ioctl.h>
  40. #include <fcntl.h>
  41. #include <stropts.h>
  42. #include <malloc.h>
  43.      
  44. /* things that aren't defined in all sun/audioio.h */
  45.  
  46. #ifndef AUDIO_ENCODING_LINEAR
  47. #define AUDIO_ENCODING_LINEAR (3)
  48. #endif
  49. #ifndef AUDIO_GETDEV
  50. #define AUDIO_GETDEV    _IOR(A, 4, int)
  51. #endif
  52. #ifndef AUDIO_DEV_UNKNOWN
  53. #define AUDIO_DEV_UNKNOWN (0)
  54. #endif
  55. #ifndef AUDIO_DEV_AMD
  56. #define AUDIO_DEV_AMD (1)
  57. #endif
  58.  
  59. LOCAL char *id = "$Id: ss10_audio.c,v 3.7 1993/01/06 17:58:39 espie Exp espie $";
  60.  
  61. LOCAL int audio;
  62.  
  63. LOCAL struct audio_info info;
  64. LOCAL char *buffer;
  65. LOCAL short *sbuffer;
  66. LOCAL int index;
  67. LOCAL int dsize;
  68.  
  69. LOCAL int stereo;
  70. LOCAL int primary, secondary;
  71.  
  72. void set_mix(percent)
  73. int percent;
  74.     {
  75.     percent *= 256;
  76.     percent /= 100;
  77.     primary = percent;
  78.     secondary = 512 - percent;
  79.     }
  80.  
  81. #define abs(x) ((x) < 0 ? -(x) : (x))
  82.  
  83. LOCAL int available(f)
  84. int f;
  85.     {
  86.     static int possible[] = { 8000, 9600, 11025, 16000, 18900, 22050, 32000,
  87.         37800, 44100, 48000, 0};
  88.     int best = 0;
  89.     int i;
  90.  
  91.     for (i = 0; possible[i]; i++)
  92.         if (abs(possible[i] - f) < abs(best - f))
  93.             best = possible[i];
  94.     return best;
  95.     }
  96.  
  97. int open_audio(f, s)
  98. int f;
  99. int s;
  100.     {
  101.     int type;
  102.  
  103.     audio = open("/dev/audio", O_WRONLY|O_NDELAY);
  104.     if (audio == -1)
  105.         {
  106.         fprintf(stderr, "Error: could not open audio\n");
  107.         end_all();
  108.         }
  109.     if (f == 0)
  110.         f = 22050;
  111.         /* round frequency to acceptable value */
  112.     f = available(f);
  113.  
  114.         /* check whether we know about AUDIO_ENCODING_LINEAR */
  115.     if (ioctl(audio, AUDIO_GETDEV, &type) ||
  116.     type == AUDIO_DEV_UNKNOWN || type == AUDIO_DEV_AMD)
  117.         {
  118.             /* not a ss 10 -> revert to base quality audio */
  119.         stereo = 0;
  120.         dsize = 1;
  121.         info.play.sample_rate = 8000;
  122.         info.play.encoding = AUDIO_ENCODING_ULAW;
  123.         info.play.channels = 1;
  124.         }
  125.     else
  126.         {
  127.             /* tentative set up */
  128.         stereo = s;
  129.         AUDIO_INITINFO(&info);
  130.         info.play.sample_rate = f;
  131.         info.play.precision = 16;
  132.         dsize = 2;
  133.         if (stereo)
  134.             {
  135.             info.play.channels = 2;
  136.             set_mix(30);
  137.             }
  138.         else
  139.             info.play.channels = 1;
  140.             /* try it */
  141.         info.play.encoding = AUDIO_ENCODING_LINEAR;
  142.         if (ioctl(audio, AUDIO_SETINFO, &info) != 0)
  143.             /* didn't work: fatal problem */
  144.             end_all();
  145.         }
  146.     index = 0;
  147.     buffer = (char *)malloc(dsize * info.play.channels * info.play.sample_rate);
  148.     sbuffer = (short *) buffer;
  149.     if (!buffer)
  150.         end_all();
  151.     return info.play.sample_rate;
  152.     }
  153.  
  154. void set_synchro(s)
  155. BOOL s;
  156.     {
  157.     }
  158.  
  159. int update_frequency()
  160.     {
  161.     int oldfreq;
  162.  
  163.     oldfreq = info.play.sample_rate;
  164.     if (ioctl(audio, AUDIO_GETINFO, &info) == 0)
  165.         {
  166.         if (oldfreq != info.play.sample_rate)
  167.             {
  168.             buffer = realloc(buffer, 
  169.                 dsize * info.play.channels * info.play.sample_rate);
  170.             sbuffer = (short *)buffer;
  171.             return info.play.sample_rate;
  172.             }
  173.         }
  174.     return 0;
  175.     }
  176.  
  177.  
  178. LOCAL int sign(x)
  179. unsigned char x;
  180.     {
  181.     return x;
  182.     }
  183.  
  184. /************************************************************************/
  185. /*      For routine 'cvt' only                                          */
  186. /************************************************************************/
  187. /*      Copyright 1989 by Rich Gopstein and Harris Corporation          */
  188. /************************************************************************/
  189.  
  190. LOCAL unsigned int cvt(ch)
  191. int ch;
  192.     {
  193.     int mask;
  194.  
  195.     if (ch < 0)
  196.         {
  197.         ch = -ch;
  198.         mask = 0x7f;
  199.         }
  200.     else
  201.         mask = 0xff;
  202.  
  203.     if (ch < 32)
  204.         {
  205.         ch = 0xF0 | 15 - (ch / 2);
  206.         }
  207.     else if (ch < 96)
  208.         {
  209.         ch = 0xE0 | 15 - (ch - 32) / 4;
  210.         }
  211.     else if (ch < 224)
  212.         {
  213.         ch = 0xD0 | 15 - (ch - 96) / 8;
  214.         }
  215.     else if (ch < 480)
  216.         {
  217.         ch = 0xC0 | 15 - (ch - 224) / 16;
  218.         }
  219.     else if (ch < 992)
  220.         {
  221.         ch = 0xB0 | 15 - (ch - 480) / 32;
  222.         }
  223.     else if (ch < 2016)
  224.         {
  225.         ch = 0xA0 | 15 - (ch - 992) / 64;
  226.         }
  227.     else if (ch < 4064)
  228.         {
  229.         ch = 0x90 | 15 - (ch - 2016) / 128;
  230.         }
  231.     else if (ch < 8160)
  232.         {
  233.         ch = 0x80 | 15 - (ch - 4064) /  256;
  234.         }
  235.     else
  236.         {
  237.         ch = 0x80;
  238.         }
  239.     return (mask & ch);
  240.     }
  241.  
  242.  
  243. void output_samples(left, right)
  244. int left, right;
  245.     {
  246.     if (stereo)
  247.         {
  248.         sbuffer[index++] = (left * primary + right * secondary)/256;
  249.         sbuffer[index++] = (right * primary + left * secondary)/256;
  250.         }
  251.     else
  252.         switch(info.play.encoding)
  253.             {
  254.         case AUDIO_ENCODING_LINEAR:
  255.             sbuffer[index++] = left + right;
  256.             break;
  257.         case AUDIO_ENCODING_ULAW:
  258.             buffer[index++] = cvt((left + right) /16);
  259.             break;
  260.             }
  261.     }
  262.  
  263. void flush_buffer()
  264.     {
  265.     write(audio, buffer, dsize * index);
  266.     index = 0;
  267.     }
  268.  
  269. void discard_buffer()
  270.     {
  271.     ioctl(audio, I_FLUSH, FLUSHW);
  272.     }
  273.  
  274. void close_audio()
  275.     {
  276.     free(buffer);
  277.     close(audio);
  278.     }
  279.  
  280.